package com.keste.portal.ui.bean;

import com.keste.model.fwk.bean.EmailBean;

import com.keste.model.fwk.util.SendEmailUtil;

import com.keste.portal.ui.util.ADFUtils;

import com.keste.portal.ui.util.JSFUtils;

import java.util.ArrayList;
import java.util.List;

import java.util.Map;

import javax.faces.event.ActionEvent;


import javax.faces.model.SelectItem;

import oracle.adf.model.BindingContext;

import oracle.adf.model.binding.DCBindingContainer;

import oracle.adf.model.binding.DCIteratorBinding;

import oracle.adf.share.logging.ADFLogger;
import oracle.adf.view.rich.component.rich.RichPopup;
import oracle.adf.view.rich.component.rich.input.RichInputText;

import oracle.adf.view.rich.component.rich.input.RichSelectOneChoice;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;
import oracle.jbo.ViewObject;
import oracle.jbo.domain.Number;
import oracle.jbo.server.EntityImpl;
import oracle.jbo.server.ViewRowImpl;

public class LeaveManagementBean {
    private RichInputText commentsBinding;
    private RichSelectOneChoice responseBinding;
    private RichInputText leaveComments;
    private RichPopup leavePopup;
    private static final String CLASSNAME =
        LeaveManagementBean.class.getName();
    private static final ADFLogger LOGGER =
        ADFLogger.createADFLogger(CLASSNAME);

    public LeaveManagementBean() {
        super();
    }

    /**
     * Setter method for commentsBinding
     * @param commentsBinding
     */
    public void setCommentsBinding(RichInputText commentsBinding) {
        this.commentsBinding = commentsBinding;
    }

    /**
     * Getter method for commentsBinding
     * @return
     */
    public RichInputText getCommentsBinding() {
        return commentsBinding;
    }

    /**
     * Setter method for responseBinding
     * @param responseBinding
     */
    public void setResponseBinding(RichSelectOneChoice responseBinding) {
        this.responseBinding = responseBinding;
    }

    /**
     * Getter method for responseBinding
     * @return
     */
    public RichSelectOneChoice getResponseBinding() {
        return responseBinding;
    }

    /**
     * Setter method for leaveComments
     * @param leaveComments
     */
    public void setLeaveComments(RichInputText leaveComments) {
        this.leaveComments = leaveComments;
    }

    /**
     * Getter method for leaveComments
     * @return
     */
    public RichInputText getLeaveComments() {
        return leaveComments;
    }

    /**
     * Setter method for leavePopup
     * @param leavePopup
     */
    public void setLeavePopup(RichPopup leavePopup) {
        this.leavePopup = leavePopup;
    }

    /**
     * Getter method for leavePopup
     * @return
     */
    public RichPopup getLeavePopup() {
        return leavePopup;
    }

    /**
     * This method is called when the user clicks on cancel in Apply/Edit LeavePopup
     * This method reverts the changes in the current row
     */
    public void undoChanges(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "undoChanges");
        LOGGER.info("" + actionEvent.toString());
        try {
            BindingContext bindingContext = BindingContext.getCurrent();
            DCBindingContainer bindingContainer =
                (DCBindingContainer)bindingContext.getCurrentBindingsEntry();
            DCIteratorBinding dcIteratorBinding =
                bindingContainer.findIteratorBinding("LeaveDetailsIterator");
            ViewObject leaveDetailsVO = dcIteratorBinding.getViewObject();
            Row leaveDetailsRow = leaveDetailsVO.getCurrentRow();
            if (leaveDetailsRow != null) {
                leaveDetailsRow.refresh(Row.REFRESH_UNDO_CHANGES |
                                        Row.REFRESH_WITH_DB_FORGET_CHANGES);
            }
            leaveDetailsVO.executeQuery();
            LOGGER.exiting(CLASSNAME, "undoChanges");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    /**
     * This method is called when the user clicks on Cancel button in LeaveDetails Table
     * This method changes the status of the leave to Cancelled and soft deletes it
     * @param actionEvent
     */
    public void onCancelLeave(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "onCancelLeave");
        LOGGER.info("" + actionEvent.toString());
        try {
            DCIteratorBinding dcIteratorBinding =
                ADFUtils.findIterator("LeaveDetailsIterator");
            Row row = dcIteratorBinding.getCurrentRow();
            row.setAttribute("Status", "CANCELLED");
            row.setAttribute("IsDeleted", 1);
            EmailBean emailBean = new EmailBean();
            emailBean.setFromEmail("noreply@keste.com");
            emailBean.setSubject("Leave Cancel");
            StringBuilder mailContent = new StringBuilder();
            mailContent.append("\nLeave Start Date    : ").append(row.getAttribute("StartDate"));
            mailContent.append("\nLeave End Date      : ").append(row.getAttribute("EndDate"));
            mailContent.append("\nNumber of Leaves    : ").append(row.getAttribute("Days"));
            mailContent.append("\nLeave Type          : ").append(row.getAttribute("LeaveType"));
            mailContent.append("\nLeave Reason        : ").append(row.getAttribute("LeaveReason"));
            emailBean.setMessage(mailContent.toString());
            emailBean.setToEmail("tarun.adupa@keste.com");
            //emailBean.setToEmail((String)row.getAttribute("ManagerEmailId"));
            SendEmailUtil.sendEmailNotification(emailBean);
            dcIteratorBinding = ADFUtils.findIterator("HistoryIterator");
            RowSetIterator rowSetIterator =
                dcIteratorBinding.getRowSetIterator();
            Row newRow = rowSetIterator.createRow();
            newRow.setAttribute("ModuleId", row.getAttribute("LeaveId"));
            newRow.setAttribute("ModuleType", "LMS");
            newRow.setAttribute("Status", row.getAttribute("Status"));
            newRow.setAttribute("Comments", "Leave Has Been Cancelled");
            rowSetIterator.insertRow(newRow);
            DCBindingContainer bindings =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            OperationBinding operationBinding =
                bindings.getOperationBinding("Commit");
            operationBinding.execute();
            JSFUtils.addFacesInformationMessage("Leave is Cancelled");
            LOGGER.exiting(CLASSNAME, "onCancelLeave");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    /**
     * This method is called when the user clicks on Save button in Apply/Edit LeavePopup
     * This method Commits the changes to Database and creates a new row in the history table
     * @param actionEvent
     */
    public void onLeaveDetailsSave(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "onLeaveDetailsSave");
        LOGGER.info("" + actionEvent.toString());
        try {
            DCIteratorBinding dcIteratorBinding =
                ADFUtils.findIterator("LeaveDetailsIterator");
            ViewObject vo = dcIteratorBinding.getViewObject();
            ViewRowImpl leaveDetailsViewRowImpl =
                (ViewRowImpl)vo.getCurrentRow();
            EntityImpl entityImpl = leaveDetailsViewRowImpl.getEntity(0);
            dcIteratorBinding = ADFUtils.findIterator("HistoryIterator");
            RowSetIterator rowSetIterator =
                dcIteratorBinding.getRowSetIterator();
            Row newRow = rowSetIterator.createRow();
            EmailBean emailBean = new EmailBean();
            if (EntityImpl.STATUS_NEW == entityImpl.getEntityState()){
                TODO:
                leaveDetailsViewRowImpl.setAttribute("EmployeeId",2);
                leaveDetailsViewRowImpl.setAttribute("Status", "PENDING");
                BindingContext context = BindingContext.getCurrent();
                BindingContainer bc = context.getCurrentBindingsEntry();
                OperationBinding setEmpOperation =
                    bc.getOperationBinding("getFilteredEmployees");
                Map params = setEmpOperation.getParamsMap();
                TODO:
                params.put("string", "2");
                Row[] rows = ((Row[])setEmpOperation.execute());
                rows[0].getAttribute("ManagerEmailId");
                newRow.setAttribute("Status", "Leave Created");
                //emailBean.setToEmail((String)rows[0].getAttribute("ManagerEmailId"));
            }
            else{
                //emailBean.setToEmail((String)leaveDetailsViewRowImpl.getAttribute("ManagerEmailId"));
                newRow.setAttribute("Status", "Leave Modified");
            }
            emailBean.setFromEmail("noreply@keste.com");
            emailBean.setSubject("Applying Leave");
            StringBuilder mailContent = new StringBuilder();
            mailContent.append("\nLeave Start Date    : ").append(leaveDetailsViewRowImpl.getAttribute("StartDate"));
            mailContent.append("\nLeave End Date      : ").append(leaveDetailsViewRowImpl.getAttribute("EndDate"));
            mailContent.append("\nNumber of Leaves    : ").append(leaveDetailsViewRowImpl.getAttribute("Days"));
            mailContent.append("\nLeave Type          : ").append(leaveDetailsViewRowImpl.getAttribute("LeaveType"));
            mailContent.append("\nLeave Reason        : ").append(leaveDetailsViewRowImpl.getAttribute("LeaveReason"));
            emailBean.setMessage(mailContent.toString());
            emailBean.setToEmail("tarun.adupa@keste.com");
            SendEmailUtil.sendEmailNotification(emailBean);
            newRow.setAttribute("ModuleId", leaveDetailsViewRowImpl.getAttribute("LeaveId"));
            newRow.setAttribute("ModuleType", "LMS");
            rowSetIterator.insertRow(newRow);
            vo.executeQuery();
            OperationBinding commitOP = ADFUtils.getOperationBinding("Commit");
            commitOP.execute();
            JSFUtils.addFacesInformationMessage("All the Changes are Saved");
            LOGGER.exiting(CLASSNAME, "onLeaveDetailsSave");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    /**
     * This method is called when the user clicks on Save button in responsePopup
     * This method Commits the changes to Database and creates a new row in the history table
     * @param actionEvent
     */
    public void onResponseSave(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "onResponseSave");
        LOGGER.info("" + actionEvent.toString());
        try {
            DCIteratorBinding dcIteratorBinding =
                ADFUtils.findIterator("LeaveDetailsIterator");
            Row row = dcIteratorBinding.getCurrentRow();
            EmailBean emailBean = new EmailBean();
            if (responseBinding.getValue().equals("1")) {
                row.setAttribute("Status", "APPROVED");
                emailBean.setSubject("Leave Approved");
                dcIteratorBinding =
                        ADFUtils.findIterator("LeaveBalanceIterator");
                Row balanceRow = dcIteratorBinding.getCurrentRow();
                balanceRow.setAttribute("AppliedLeaves",
                                        ((Number)balanceRow.getAttribute("AppliedLeaves")).add((Number)row.getAttribute("Days")));
                if (row.getAttribute("LeaveType").equals("CASUAL"))
                    balanceRow.setAttribute("CasualLeaves",
                                            ((Number)balanceRow.getAttribute("CasualLeaves")).subtract((Number)row.getAttribute("Days")));
                else if (row.getAttribute("LeaveType") == "SICK")
                    balanceRow.setAttribute("SickLeaves",
                                            ((Number)balanceRow.getAttribute("SickLeaves")).subtract((Number)row.getAttribute("Days")));
            } else {
                row.setAttribute("Status", "REJECTED");
                emailBean.setSubject("Leave Rejected"); 
            }
            row.setAttribute("IsDeleted", '1');
            emailBean.setFromEmail("noreply@keste.com");
            StringBuilder mailContent = new StringBuilder();
            mailContent.append("\nLeave Start Date    : ").append(row.getAttribute("StartDate"));
            mailContent.append("\nLeave End Date      : ").append(row.getAttribute("EndDate"));
            mailContent.append("\nNumber of Leaves    : ").append(row.getAttribute("Days"));
            mailContent.append("\nLeave Type          : ").append(row.getAttribute("LeaveType"));
            mailContent.append("\nLeave Reason        : ").append(row.getAttribute("LeaveReason"));
            emailBean.setMessage(mailContent.toString());
            TODO:
            //emailBean.setToEmail(row.getAttribute("EmployeeEmailId"));
            emailBean.setToEmail("tarun.adupa@keste.com");
            SendEmailUtil.sendEmailNotification(emailBean);
            dcIteratorBinding = ADFUtils.findIterator("HistoryIterator");
            RowSetIterator rowSetIterator =
                dcIteratorBinding.getRowSetIterator();
            Row newRow = rowSetIterator.createRow();
            newRow.setAttribute("ModuleId", row.getAttribute("LeaveId"));
            newRow.setAttribute("ModuleType", "LMS");
            newRow.setAttribute("Status", row.getAttribute("Status"));
            newRow.setAttribute("Comments", commentsBinding.getValue());
            rowSetIterator.insertRow(newRow);
            OperationBinding commitOP = ADFUtils.getOperationBinding("Commit");
            commitOP.execute();
            JSFUtils.addFacesInformationMessage("Response is Saved");
            LOGGER.exiting(CLASSNAME, "onResponseSave");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    /**
     * This method is called when the user clicks on Apply Leave button in leave management page
     * This methods opens a popup where user can edit or add the leave details
     * @param actionEvent
     */
    public void onApplyLeave(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "onApplyLeave");
        LOGGER.info("" + actionEvent.toString());
        try {
            DCBindingContainer bindings =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            OperationBinding operationBinding =
                bindings.getOperationBinding("CreateInsert");
            operationBinding.execute();
            RichPopup.PopupHints hints = new RichPopup.PopupHints();
            this.getLeavePopup().show(hints);
            LOGGER.exiting(CLASSNAME, "onApplyLeave");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    /**
     * This method is called when the user clicks on Search button in leave management page
     * This methods filters the below table appropriately
     * @param actionEvent
     */
    public void onSearchLeave(ActionEvent actionEvent) {
        LOGGER.entering(CLASSNAME, "onSearchLeave");
        LOGGER.info("" + actionEvent.toString());
        try {
            DCIteratorBinding transientIterator =
                ADFUtils.findIterator("SearchLeavesTransientIterator");
            DCBindingContainer bindings =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            Row row = transientIterator.getCurrentRow();
            OperationBinding operationBinding =
                bindings.getOperationBinding("searchLeaves");
            String action = (String)ADFUtils.evaluateEL("#{pageFlowScope.action}");
            if(action!=null){
                if(action.equals("LMS"))
                operationBinding.getParamsMap().put("empId",
                                                    2);
                else 
                operationBinding.getParamsMap().put("managerId",
                                                    1); 
            }
            else
            operationBinding.getParamsMap().put("empId",
                                                row.getAttribute("EmployeeId"));
            operationBinding.getParamsMap().put("leaveType",
                                                row.getAttribute("LeaveType"));
            operationBinding.getParamsMap().put("startDate",
                                                row.getAttribute("FromDate"));
            operationBinding.getParamsMap().put("endDate",
                                                row.getAttribute("ToDate"));
            operationBinding.getParamsMap().put("status",
                                                row.getAttribute("LeaveStatus"));
            operationBinding.execute();
            LOGGER.exiting(CLASSNAME, "onSearchLeave");
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.severe(e.getMessage());
        }
    }

    public List employeeAutoSuggest(String string) {
        // Add event code here...
        BindingContext context = BindingContext.getCurrent();
        BindingContainer bc = context.getCurrentBindingsEntry();
        OperationBinding setEmpOperation =
            bc.getOperationBinding("getFilteredEmployees");
        Map params = setEmpOperation.getParamsMap();
        params.put("string", string);
        Row[] r = (Row[])setEmpOperation.execute();
        List<SelectItem> li = new ArrayList<SelectItem>();
        SelectItem si;
        String str = "";
        for (int i = 0; i < r.length; i++) {
            str = "";
            if ((Number)r[i].getAttribute("EmployeeId") != null)
                str += (Number)r[i].getAttribute("EmployeeId") + " | ";
            if ((String)r[i].getAttribute("FirstName") != null)
                str += (String)r[i].getAttribute("FirstName") + " ";
            if ((String)r[i].getAttribute("MidName") != null)
                str += (String)r[i].getAttribute("MidName") + " ";
            if ((String)r[i].getAttribute("LastName") != null)
                str += (String)r[i].getAttribute("LastName") + " ";
            str += "| ";
            if ((String)r[i].getAttribute("EmailId") != null)
                str += (String)r[i].getAttribute("EmailId");
            si = new SelectItem(r[i].getAttribute("EmployeeId"), str);
            li.add(si);
        }
        return li;
    }
}
